"use client";

import * as React from "react";
import { ChevronDown, ChevronRight, Minus, Plus } from "lucide-react";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";
import { Badge } from "@/components/ui/badge";
import { ScrollArea } from "@/components/ui/scroll-area";
import { DepartmentNode } from "@/lib/users/knox-service";
import { getDomainLabel, getDomainColor } from "./domain-constants";

interface DepartmentAssignment {
  id: number;
  departmentCode: string;
  assignedDomain: string;
  description?: string | null;
}

interface DepartmentTreeViewProps {
  departments: DepartmentNode[];
  selectedDepartments: string[];
  onSelectionChange: (selected: string[]) => void;
  assignments: DepartmentAssignment[];
  className?: string;
}

interface TreeNodeProps {
  node: DepartmentNode;
  selectedDepartments: string[];
  onToggle: (departmentCode: string) => void;
  expandedNodes: Set<string>;
  onExpandToggle: (departmentCode: string) => void;
  assignments: DepartmentAssignment[];
  level: number;
}

function TreeNode({ 
  node, 
  selectedDepartments, 
  onToggle, 
  expandedNodes, 
  onExpandToggle, 
  assignments, 
  level 
}: TreeNodeProps) {
  const isExpanded = expandedNodes.has(node.departmentCode);
  const hasChildren = node.children.length > 0;
  
  // 현재 부서에 할당된 도메인 찾기
  const assignment = assignments.find(a => a.departmentCode === node.departmentCode);
  
  // 현재 노드의 선택 상태 확인
  const isSelected = selectedDepartments.includes(node.departmentCode);
  
  // 하위 노드들 중 선택된 것이 있는지 확인 (부분 선택 상태 표시용)
  const hasSelectedChildren = React.useMemo(() => {
    if (!hasChildren) return false;
    
    const getAllChildCodes = (dept: DepartmentNode): string[] => {
      const codes: string[] = [];
      dept.children.forEach(child => {
        codes.push(child.departmentCode);
        codes.push(...getAllChildCodes(child));
      });
      return codes;
    };
    
    const childCodes = getAllChildCodes(node);
    return childCodes.some(code => selectedDepartments.includes(code));
  }, [node, selectedDepartments, hasChildren]);

  const handleToggle = () => {
    onToggle(node.departmentCode);
  };

  const handleExpandToggle = () => {
    if (hasChildren) {
      onExpandToggle(node.departmentCode);
    }
  };

  return (
    <div className="select-none">
      <div 
        className={cn(
          "flex items-center gap-2 py-2 px-3 hover:bg-accent/50 rounded-md transition-colors",
          (isSelected || (!isSelected && hasSelectedChildren)) && "bg-accent/20"
        )}
        style={{ marginLeft: `${level * 16}px` }}
      >
        {/* 확장/축소 버튼 */}
        <div className="flex items-center justify-center w-5 h-5">
          {hasChildren ? (
            <Button
              variant="ghost"
              size="sm"
              className="h-5 w-5 p-0 hover:bg-transparent"
              onClick={handleExpandToggle}
            >
              {isExpanded ? (
                <ChevronDown className="h-3 w-3" />
              ) : (
                <ChevronRight className="h-3 w-3" />
              )}
            </Button>
          ) : null}
        </div>

        {/* 체크박스 */}
        <div className="flex items-center">
          <Checkbox
            checked={isSelected}
            onCheckedChange={handleToggle}
            className={cn(
              "h-4 w-4",
              !isSelected && hasSelectedChildren && "[&>*:first-child]:opacity-50"
            )}
          />
        </div>

        {/* 부서 정보 */}
        <div className="flex-1 min-w-0 cursor-pointer" onClick={handleToggle}>
          <div className="flex items-center gap-2">
            <span className={cn(
              "font-medium truncate",
              (isSelected || (!isSelected && hasSelectedChildren)) && "text-primary"
            )}>
              {node.departmentName || node.departmentCode}
            </span>
            
            {/* 할당된 도메인 표시 */}
            {assignment && (
              <Badge 
                className={cn(
                  "text-xs shrink-0",
                  getDomainColor(assignment.assignedDomain)
                )}
                variant="outline"
              >
                {getDomainLabel(assignment.assignedDomain)}
              </Badge>
            )}
          </div>
          
          {/* 부서 코드 */}
          <div className="text-xs text-muted-foreground truncate">
            {node.departmentCode}
            {assignment?.description && (
              <span className="ml-1">• {assignment.description}</span>
            )}
          </div>
        </div>
      </div>

      {/* 하위 노드들 */}
      {hasChildren && isExpanded && (
        <div className="mt-1">
          {node.children.map((child) => (
            <TreeNode
              key={child.departmentCode}
              node={child}
              selectedDepartments={selectedDepartments}
              onToggle={onToggle}
              expandedNodes={expandedNodes}
              onExpandToggle={onExpandToggle}
              assignments={assignments}
              level={level + 1}
            />
          ))}
        </div>
      )}
    </div>
  );
}

export function DepartmentTreeView({
  departments,
  selectedDepartments,
  onSelectionChange,
  assignments,
  className,
}: DepartmentTreeViewProps) {
  const [expandedNodes, setExpandedNodes] = React.useState<Set<string>>(new Set());

  // 부서 토글 핸들러
  const handleToggle = (departmentCode: string) => {
    const findNode = (nodes: DepartmentNode[], code: string): DepartmentNode | null => {
      for (const node of nodes) {
        if (node.departmentCode === code) return node;
        const found = findNode(node.children, code);
        if (found) return found;
      }
      return null;
    };

    const getAllChildCodes = (node: DepartmentNode): string[] => {
      const codes: string[] = [];
      node.children.forEach(child => {
        codes.push(child.departmentCode);
        codes.push(...getAllChildCodes(child));
      });
      return codes;
    };

    const targetNode = findNode(departments, departmentCode);
    if (!targetNode) return;

    const isCurrentlySelected = selectedDepartments.includes(departmentCode);
    
    let newSelected: string[];
    if (isCurrentlySelected) {
      // 선택 해제: 해당 부서만 제거 (하위 부서는 유지, 상위 부서에도 영향 없음)
      newSelected = selectedDepartments.filter(code => code !== departmentCode);
    } else {
      // 선택: 해당 부서 + 모든 하위 부서 추가
      const childCodes = getAllChildCodes(targetNode);
      const codesToAdd = [departmentCode, ...childCodes].filter(code => !selectedDepartments.includes(code));
      newSelected = [...selectedDepartments, ...codesToAdd];
    }

    onSelectionChange(newSelected);
  };

  // 노드 확장/축소 핸들러
  const handleExpandToggle = (departmentCode: string) => {
    const newExpanded = new Set(expandedNodes);
    if (newExpanded.has(departmentCode)) {
      newExpanded.delete(departmentCode);
    } else {
      newExpanded.add(departmentCode);
    }
    setExpandedNodes(newExpanded);
  };

  // 전체 확장/축소
  const handleExpandAll = () => {
    if (expandedNodes.size === 0) {
      const getAllCodes = (nodes: DepartmentNode[]): string[] => {
        const codes: string[] = [];
        nodes.forEach(node => {
          if (node.children.length > 0) {
            codes.push(node.departmentCode);
            codes.push(...getAllCodes(node.children));
          }
        });
        return codes;
      };
      setExpandedNodes(new Set(getAllCodes(departments)));
    } else {
      setExpandedNodes(new Set());
    }
  };

  // 전체 선택/해제
  const handleSelectAll = () => {
    if (selectedDepartments.length === 0) {
      // 전체 선택
      const allCodes: string[] = [];
      const collectCodes = (nodes: DepartmentNode[]) => {
        nodes.forEach(node => {
          allCodes.push(node.departmentCode);
          collectCodes(node.children);
        });
      };
      collectCodes(departments);
      onSelectionChange(allCodes);
    } else {
      // 전체 해제
      onSelectionChange([]);
    }
  };

  return (
    <div className={cn("border rounded-lg", className)}>
      {/* 헤더 */}
      <div className="flex items-center justify-between p-3 border-b bg-muted/30">
        <h3 className="font-medium">조직도</h3>
        <div className="flex gap-2">
          <Button
            variant="outline"
            size="sm"
            onClick={handleExpandAll}
            className="text-xs"
          >
            {expandedNodes.size === 0 ? (
              <>
                <Plus className="mr-1 h-3 w-3" />
                전체 펼치기
              </>
            ) : (
              <>
                <Minus className="mr-1 h-3 w-3" />
                전체 접기
              </>
            )}
          </Button>
          <Button
            variant="outline"
            size="sm"
            onClick={handleSelectAll}
            className="text-xs"
          >
            {selectedDepartments.length === 0 ? "전체 선택" : "선택 해제"}
          </Button>
        </div>
      </div>

      {/* 트리 본문 */}
      <ScrollArea className="h-[80vh] p-2">
        {departments.length === 0 ? (
          <div className="text-center py-8 text-muted-foreground">
            부서 정보가 없습니다
          </div>
        ) : (
          <div className="space-y-1">
            {departments.map((dept) => (
              <TreeNode
                key={dept.departmentCode}
                node={dept}
                selectedDepartments={selectedDepartments}
                onToggle={handleToggle}
                expandedNodes={expandedNodes}
                onExpandToggle={handleExpandToggle}
                assignments={assignments}
                level={0}
              />
            ))}
          </div>
        )}
      </ScrollArea>

      {/* 푸터 */}
      {selectedDepartments.length > 0 && (
        <div className="border-t p-3 bg-muted/30">
          <div className="text-sm text-muted-foreground">
            선택된 부서: <span className="font-medium text-foreground">{selectedDepartments.length}개</span>
          </div>
        </div>
      )}
    </div>
  );
} 